package com.heima.comment.service.impl;

import com.heima.comment.feign.UserFeign;
import com.heima.comment.service.CommentService;
import com.heima.model.comment.dtos.CommentDto;
import com.heima.model.comment.dtos.CommentLikeDto;
import com.heima.model.comment.dtos.CommentSaveDto;
import com.heima.model.comment.pojos.ApComment;
import com.heima.model.comment.pojos.ApCommentLike;
import com.heima.model.comment.vo.ApCommentVo;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.pojos.ApUser;
import com.heima.utils.threadlocal.AppThreadLocalUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Consumer;
import java.util.stream.Collectors;

@Service
public class CommentServiceImpl implements CommentService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private UserFeign userFeign;
    /**
     * 保存评论
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult saveComment(CommentSaveDto dto) {
        //1校验参数
        if (dto.getArticleId() == null || dto == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //评论文字要小于140字
        if (dto.getContent() != null && dto.getContent().length() > 140) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "评论内容不能大于140字");
        }
        //2.判断是否登录
        ApUser user = AppThreadLocalUtils.getUser();
        if (user == null) {
            //未登录
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        //3.安全过滤


        //4. 保存评论
        ApUser apUser = userFeign.findUserById(user.getId().longValue());
        if (apUser == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "当前登录信息有误!!");
        }
        ApComment apComment = new ApComment();
        apComment.setAuthorId(apUser.getId());
        apComment.setAuthorName(apUser.getName());
        apComment.setContent(dto.getContent());
        apComment.setEntryId(dto.getArticleId());
        apComment.setCreatedTime(new Date());
        apComment.setUpdatedTime(new Date());
        apComment.setImage(apUser.getImage());
        apComment.setLikes(0);
        apComment.setReply(0);
        apComment.setType((short) 0);
        apComment.setFlag((short) 0);
        mongoTemplate.save(apComment);
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 点赞评论
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult like(CommentLikeDto dto) {
        //1.检查参数
        if (dto == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //2.判断是否登录
        ApUser apUser = AppThreadLocalUtils.getUser();
        if (apUser == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        //3.点赞操作
        ApComment apComment = mongoTemplate.findById(dto.getCommentId(), ApComment.class);
        if (apComment != null && dto.getOperation() == 0) {
            //增加apComment表中点赞的次数
            apComment.setLikes(apComment.getLikes() + 1);
            mongoTemplate.save(apComment);
            //保存app评论信息的点赞
            ApCommentLike apCommentLike = new ApCommentLike();
            apCommentLike.setAuthorId(apUser.getId());
            apCommentLike.setCommentId(dto.getCommentId());
            apCommentLike.setOperation(dto.getOperation());
            mongoTemplate.save(apCommentLike);
        } else {
            //4.取消点赞
            //更新评论的点赞次数
            apComment.setLikes(apComment.getLikes() <= 0 ? 0 : apComment.getLikes() - 1);
            mongoTemplate.save(apComment);
            //修改app评论信息的点赞
            /*Query query=Query.query(Criteria.where("authorId").is(apUser.getId()).and("commentId").is(dto.getCommentId()));
            mongoTemplate.remove(query,ApCommentLike.class);*/

            Query query = Query.query(Criteria.where("authorId").is(apUser.getId()).and("commentId").is(dto.getCommentId()));
            Update update = Update.update("operation", dto.getOperation());
            mongoTemplate.upsert(query, update, ApCommentLike.class);
        }
        //5.数据返回
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("likes", apComment.getLikes());
        return ResponseResult.okResult(resultMap);
    }

    /**
     * 根据文章id查询评论列表
     *
     * @return
     */
    @Override
    public ResponseResult findByArticleId(CommentDto dto) {
        //校验参数
        if (dto == null || dto.getArticleId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        int size = 10;
        //按照文章id过滤，设置分页和排序
        Query query = Query.query(Criteria.where("entryId").is(dto.getArticleId()));
               /* .and("createdTime").lt(dto.getMinDate()));*/
        query.limit(size).with(Sort.by(Sort.Order.desc("createdTime")));
        List<ApComment> list = mongoTemplate.find(query, ApComment.class);
        //3.数据封装返回
        //3.1 用户未登录 加载数据
        ApUser user = AppThreadLocalUtils.getUser();
        if (user == null) {
            return ResponseResult.okResult(list);
        }
        //3.2 用户已登录，加载数据，需要判断当前用户点赞了哪些评论
        List<String> idList = list.stream().map(ApComment::getId).collect(Collectors.toList());
        Query query1 = Query.query(Criteria.where("authorId").is(user.getId())
                .and("commentId").in(idList));
        List<ApCommentLike> apCommentLikes = mongoTemplate.find(query1, ApCommentLike.class);

        List<ApCommentVo> resultList = new ArrayList<>();
        if (list != null && apCommentLikes != null) {
            list.stream().forEach(new Consumer<ApComment>() {
                @Override
                public void accept(ApComment apComment) {
                    ApCommentVo apCommentVo = new ApCommentVo();
                    BeanUtils.copyProperties(apComment,apCommentVo);
                    for (ApCommentLike apCommentLike : apCommentLikes) {
                        if (apComment.getId().equals(apCommentLike.getCommentId())){
                            apCommentVo.setOperation((short) 0);
                            break;
                        }
                    }
                    resultList.add(apCommentVo);
                }
            });
            return  ResponseResult.okResult(resultList);
        }else {
            return  ResponseResult.okResult(list);
        }
    }
}
